﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WinHID
{
    internal static class JConvert
    {
        public static int ToInt(this object o)
        {
            return Convert.ToInt32(o);
        }

        /// <summary>
        /// byte[]转十六进制字符串
        /// </summary>
        /// <param name="bStr">byte串</param>
        /// <param name="interval">间隔符</param>
        /// <returns>十六进制字符串</returns>
        public static string BytesToHex(byte[] bStr, string interval = "")
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte item in bStr)
            {
                sb.Append(item.ToString("X2") + interval);
            }
            return sb.ToString().Trim();
        }

        /// <summary>
        /// 十六进制字符串转byte[]
        /// </summary>
        /// <param name="hexStr">十六进制字符串</param>
        /// <returns>byte串</returns>
        public static byte[] HexToBytes(string hexStr)
        {
            hexStr = hexStr.Replace(" ", "");
            if (hexStr.Length % 2 == 1)
            {
                hexStr = "0" + hexStr;
            }
            int count = hexStr.Length / 2;
            byte[] bStr;
            if (count > 0)
            {
                bStr = new byte[count];

                for (int i = 0; i < count; i++)
                {
                    bStr[i] = Convert.ToByte(hexStr.Substring(i * 2, 2), 16);
                }
            }
            else
            {
                bStr = null;
            }
            return bStr;
        }

        public static string CRC16(string hex)
        {
            var bytes = HexToBytes(hex);
            var bcrc = CRC16(bytes.ToList());
            string scrc = BytesToHex(bcrc.ToArray());
            return scrc;
        }

        public static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
        {
            if (value == null || !value.Any())
                throw new ArgumentException("");

            //运算
            ushort crc = crcInit;
            for (int i = 0; i < value.Count; i++)
            {
                crc = (ushort)(crc ^ (value[i]));
                for (int j = 0; j < 8; j++)
                {
                    crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
                }
            }
            byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
            byte lo = (byte)(crc & 0x00FF);         //低位置

            List<byte> buffer = new List<byte>
            {
                //添加校验原始值
                //buffer.AddRange(value);
                //添加校验位值                
                hi,
                lo
            };

            //加上原始校验值返回
            return buffer;
        }
    }
}
